﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing.Text;

namespace Walson.Windows.Forms
{
    public partial class PieMeter : Control
    {

        private float _Value = 50;
        public float Value
        {
            get
            {
                return _Value;
            }
            set
            {
                if (_Value != value)
                {
                    _Value = value;
                    this.Invalidate();
                }
            }
        }

        private Color _PanelColor = Color.Gray;
        public Color PanelColor
        {
            get
            {
                return _PanelColor;
            }
            set
            {
                if (_PanelColor != value)
                {
                    _PanelColor = value;
                    this.Invalidate();
                }
            }
        }

        private Color _PanelBorderColor = Color.White;
        public Color PanelBorderColor
        {
            get
            {
                return _PanelBorderColor;
            }
            set
            {
                if (_PanelBorderColor != value)
                {
                    _PanelBorderColor = value;
                    this.Invalidate();
                }
            }
        }

        private Color _TextPanelColor = Color.FromArgb(16, 16, 49);
        public Color TextPanelColor
        {
            get
            {
                return _TextPanelColor;
            }
            set
            {
                if (_TextPanelColor != value)
                {
                    _TextPanelColor = value;
                    this.Invalidate();
                }
            }
        }

        private Color _TextPanelBorderColor = Color.White;
        public Color TextPanelBorderColor
        {
            get
            {
                return _TextPanelBorderColor;
            }
            set
            {
                if (_TextPanelBorderColor != value)
                {
                    _TextPanelBorderColor = value;
                    this.Invalidate();
                }
            }
        }


        private Color _BackColor = Color.Transparent;
        /// <summary>
        /// 背景色
        /// </summary>
        public override Color BackColor
        {
            get
            {
                return _BackColor;
            }
            set
            {
                if (_BackColor != value)
                {
                    _BackColor = value;
                    this.Invalidate();
                }
            }
        }

        private Color _ForeColor = Color.White;
        /// <summary>
        /// 前景色
        /// </summary>
        public override Color ForeColor
        {
            get
            {
                return _ForeColor;
            }
            set
            {
                if (_ForeColor != value)
                {
                    _ForeColor = value;
                    this.Invalidate();
                }
            }
        }

        private Color _MarkerColor = Color.White;
        public Color MarkerColor
        {
            get
            {
                return _MarkerColor;
            }
            set
            {
                if (_MarkerColor != value)
                {
                    _MarkerColor = value;
                    this.Invalidate();
                }
            }
        }

        private Color _EndMarkerColor = Color.Red;
        public Color EndMarkerColor
        {
            get
            {
                return _EndMarkerColor;
            }
            set
            {
                if (_EndMarkerColor != value)
                {
                    _EndMarkerColor = value;
                    this.Invalidate();
                }
            }
        }

        private int _ShortMarkerLength = 5;
        public int ShortMarkerLength
        {
            get
            {
                return _ShortMarkerLength;
            }
            set
            {
                if (_ShortMarkerLength != value)
                {
                    _ShortMarkerLength = value;
                    this.Invalidate();
                }
            }
        }

        private int _LongMarkerLength = 10;
        public int LongMarkerLength
        {
            get
            {
                return _LongMarkerLength;
            }
            set
            {
                if (_LongMarkerLength != value)
                {
                    _LongMarkerLength = value;
                    this.Invalidate();
                }
            }
        }


        public PieMeter()
        {
            InitializeComponent();

            this.DoubleBuffered = true;
        }

        protected /*override*/ void OnPaint0(PaintEventArgs e)
        {
            using (Bitmap bmp = new Bitmap(210, 170))
            {
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.TextRenderingHint = TextRenderingHint.AntiAlias;

                    Pen panelBorderPen = new Pen(_PanelBorderColor, 2f);
                    Pen textPanelBorderPen=new Pen(_TextPanelBorderColor,2f);
                    Pen markerPen = new Pen(_MarkerColor, 2f);

                    g.TranslateTransform(0, -10);

                    RectangleF rect = new RectangleF(5, -25, 200,200);
                    Rectangle rect2 = new Rectangle(5, -25, 200, 200);

                    

                    g.FillPie(new SolidBrush(_PanelColor), rect2, 0, 210 * _Value / 100f);
                    g.DrawArc(panelBorderPen, rect, 0, 215);
                    g.DrawPie(panelBorderPen, rect, 0, 210 * _Value / 100f);
 
                    
                    g.TranslateTransform(105, 75);
                    g.RotateTransform(90);
                    PointF[] line = new PointF[3];
                    line[0] = new PointF(0, -90);
                    line[1] = new PointF(0, -95);
                    line[2] = new PointF(0, -100);
                    for (int i = 0; i <= 20;i++ )
                    {
                        if (i % 2 == 0)
                            g.DrawLine(panelBorderPen, line[0], line[2]);
                        else
                            g.DrawLine(panelBorderPen, line[1], line[2]);
                        g.RotateTransform(10.5f);
                    }
                    g.RotateTransform(-5.5f);
                    line[0] = new PointF(0, -100);
                    line[1] = new PointF(0, -110);
                    g.DrawLine(new Pen(Color.Red, 2), line[0], line[1]);
                    g.ResetTransform();

                    g.TranslateTransform(0, -10);
                    string str = _Value.ToString() + "%";
                    SizeF stringSize = g.MeasureString(str, this.Font);

                    rect2 = new Rectangle(105, 75 - (int)stringSize.Height, 100,(int) stringSize.Height);
                    g.FillRectangle(new SolidBrush(_TextPanelColor), rect2);
                    g.DrawRectangle(textPanelBorderPen,rect2);

                     g.DrawString(str, this.Font, new SolidBrush(this.ForeColor), rect2.Left + (rect2.Width / 2 - stringSize.Width / 2), rect2.Top);
                }
                e.Graphics.DrawImage(bmp, new Rectangle(0, 0, this.Width, this.Height), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
            }

            base.OnPaint(e);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            using (Bitmap bmp = new Bitmap(this.Width, this.Height))
            {
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.TextRenderingHint = TextRenderingHint.AntiAlias;

                    float r = 0f;
                    r = this.Width > this.Height ? this.Height * 0.49f : this.Width * 0.49f;

                    Pen pieBorderPen = new Pen(_PanelBorderColor, 2f);
                    Pen textBorderPen = new Pen(_TextPanelBorderColor, 2f);
                    Pen markerPen = new Pen(_MarkerColor, 2f);
                    Pen endMarkerPen = new Pen(_EndMarkerColor, 2f);
                    SolidBrush pieBrush = new SolidBrush(_PanelColor);
                    SolidBrush textPanelBrush = new SolidBrush(_TextPanelColor);
                    SolidBrush textBrush=new SolidBrush(this.ForeColor);

                    RectangleF rectPieF = new RectangleF(1, 1, r * 2f, r * 2f);

                    g.FillPie(pieBrush, 1f, 1f, r * 2f, r * 2f, 0f, 210f * _Value / 100f);
                    //g.DrawPie(pieBorderPen, 1f, 1f, r * 2f, r * 2f, 0f, 210f * _Value / 100f);

                    // 绘制外圈
                    g.DrawArc(pieBorderPen, rectPieF, 0f, 215f);

                    g.TranslateTransform(r + 1, r + 1);
                    GraphicsState gs = g.Save();

                    // 绘制饼图的两条直边线
                    g.RotateTransform(90 + 210f * _Value / 100f);
                    PointF[] line = new PointF[2];
                    line[0] = new PointF(0, -r);
                    line[1] = new PointF(0, 0);
                    g.DrawLine(pieBorderPen, line[0], line[1]);

                    g.Restore(gs);

                    //绘制刻度
                    g.RotateTransform(90);
                    line = new PointF[3];
                    line[0] = new PointF(0, -r+_LongMarkerLength);
                    line[1] = new PointF(0, -r+_ShortMarkerLength);
                    line[2] = new PointF(0, -r);
                    for (int i = 0; i <= 20; i++)
                    {
                        if (i % 2 == 0)
                            g.DrawLine(markerPen, line[0], line[2]);
                        else
                            g.DrawLine(markerPen, line[1], line[2]);
                        g.RotateTransform(10.5f);
                    }
                    g.RotateTransform(-5.5f);
                    line[0] = new PointF(0, -r);
                    line[1] = new PointF(0, -r-_LongMarkerLength);
                    g.DrawLine(endMarkerPen, line[0], line[1]);
                    g.ResetTransform();

                    //绘制文本框和文字
                    string str = _Value.ToString() + "%";
                    SizeF stringSize = g.MeasureString(str, this.Font);
                    StringFormat sf = new StringFormat();
                    sf.Alignment = System.Drawing.StringAlignment.Center;
                    sf.LineAlignment = StringAlignment.Center;
                    sf.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;

                    g.TranslateTransform(r + 1, r + 1);
                    RectangleF textRectF = new RectangleF(0, -stringSize.Height*1.5f, r, stringSize.Height * 1.5f);
                    g.FillRectangle(textPanelBrush, textRectF);
                    g.DrawRectangle(textBorderPen, textRectF.Left, textRectF.Top, textRectF.Width, textRectF.Height);
                    g.DrawString(str, this.Font, textBrush, textRectF, sf);
                }
                e.Graphics.DrawImage(bmp, 0, 0);
            }
            base.OnPaint(e);
        }
    }
}
